package com.ygqh.baby.service.impl;

import com.ygqh.baby.ao.*;
import com.ygqh.baby.mapper.YgPrepayBookRecordMapper;
import com.ygqh.baby.model.*;
import com.ygqh.baby.po.*;
import com.ygqh.baby.service.*;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.ExceptionUtil;

import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

@Service
public class YgPrepayBookRecordServiceImpl implements YgPrepayBookRecordService {

	protected final Logger logger = LoggerFactory.getLogger(this.getClass());
	private final ExecutorService executorService = Executors.newFixedThreadPool(3);
	private final Long CANCELBOOK_COUPON_ID = 311L;

	@Autowired
	private YgPrepayBookRecordMapper ygPrepayBookRecordMapper;
	@Autowired
	private YgStockService ygStockService;
	@Autowired
	private DocumentConstant documentConstant;
	@Autowired
	private YgFrameCodeService ygFrameCodeService;
	@Autowired
	private YgOrderLogService ygOrderLogService;
	@Autowired
	private YgProductBookService ygProductBookService;
	@Autowired
	private YgShoppingCarService ygShoppingCarService;
	@Autowired
	private YgUserAddressService ygUserAddressService;
	@Autowired
	private YgOrderService ygOrderService;
	@Autowired
	private YgCardCouponDetailService ygCardCouponDetailService;
	@Autowired
	private YgCouponDetailService ygCouponDetailService;
	@Autowired
	private YgOrderPaymentService ygOrderPaymentService;
	@Autowired
	private YgReturnOrderService ygReturnOrderService;
	@Autowired
	private YgReturnOrderLogService ygReturnOrderLogService;
	@Autowired
	private YgUserService ygUserService;

	@Override
	public List<YgPrepayBookRecord> find() {
		YgPrepayBookRecordExample example = new YgPrepayBookRecordExample();
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
		return ygPrepayBookRecordMapper.selectByExample(example);
	}

	@Override
	public int findCount() {
		YgPrepayBookRecordExample example = new YgPrepayBookRecordExample();
		example.createCriteria().andStatusEqualTo(DataStatus.Valid.name());
		return ygPrepayBookRecordMapper.countByExample(example);
	}

	@Override
	public YgPrepayBookRecord findById(Long id) {
		return ygPrepayBookRecordMapper.selectByPrimaryKey(id);
	}

	@Override
	public int save(YgPrepayBookRecord ygPrepayBookRecord) {
		return ygPrepayBookRecordMapper.insertSelective(ygPrepayBookRecord);
	}

	@Override
	public int update(YgPrepayBookRecord ygPrepayBookRecord) {
		return ygPrepayBookRecordMapper.updateByPrimaryKeySelective(ygPrepayBookRecord);
	}

	@Override
	public ResultSet<ProductBookRecordModel> search(QueryInfo queryInfo, String q, Long userId, YgPrepayBookRecord.RecordStatus recordStatus, String userName) {
		List<ProductBookRecordModel> list = this.findList(queryInfo, q, userId, recordStatus, userName);
		int count = ygPrepayBookRecordMapper.countSuper(q, userId, recordStatus, userName);
		return new ResultSet<>(count, list);
	}

	@Override
	public int deleteSoft(Long[] ids) {
		Assert.notEmpty(ids);
		YgPrepayBookRecordExample example = new YgPrepayBookRecordExample();
		example.createCriteria().andIdIn(Arrays.asList(ids));
		YgPrepayBookRecord record = new YgPrepayBookRecord();
		record.setStatus(DataStatus.Delete);
		return ygPrepayBookRecordMapper.updateByExampleSelective(record, example);
	}

	@Override
	public int deleteSoft(Long id) {
		return this.deleteSoft(new Long[]{id});
	}

	@Override
	public int saveOrUpdate(YgPrepayBookRecord ygPrepayBookRecord) {
		int r;
		if (ygPrepayBookRecord.getId() != null) {
			r = this.update(ygPrepayBookRecord);
		} else {
			r = this.save(ygPrepayBookRecord);
		}
		return r;
	}

	@Override
	public ProductBookRecordModel findByRecordCode(Long recordCode) {
		if (recordCode == null) {
			return null;
		}
		List<ProductBookRecordModel> recordList = this.findByRecordCode(Collections.singletonList(recordCode));
		return CollectionUtils.isEmpty(recordList) ? null : recordList.get(0);
	}

	@Override
	public List<ProductBookRecordModel> findByRecordCode(List<Long> recordCodeList) {
		if (CollectionUtils.isEmpty(recordCodeList)) {
			return new ArrayList<>();
		}
		return ygPrepayBookRecordMapper.selectByRecordCode(recordCodeList);
	}

	@Override
	public Message commitRecord(Long userId, YgShoppingCarModel carModel, YgProductBook productBook) {
		if (ProductStatus.InStock.equals(carModel.getSaleStatus())) {
			return Message.error("【" + carModel.getProductName() + "】已下架", null);
		}
		YgStock stock = ygStockService.findBySkuCode(carModel.getSkuCode());
		if (carModel.getQuantity().compareTo(stock.getAmount()) > 0) { // 校验库存
			return Message.error("【" + carModel.getProductName() + "】" + documentConstant.getSTOCK_LESS(), null);
		}
		// 建立记录信息
		YgPrepayBookRecord record = new YgPrepayBookRecord();
		record.setRecordCode(ygFrameCodeService.getFrameCode(CodeType.Order, new Date()));
		record.setUserId(userId);

		// 设置商品信息
		record.setSupplierId(carModel.getSupplierId());
		record.setSkuId(carModel.getSkuId());
		record.setSkuCode(carModel.getSkuCode());
		record.setProductName(carModel.getProductName());
		record.setShortName(carModel.getShortName());
		record.setSalePrice(carModel.getRealSalesPrice());
		record.setSize(carModel.getSizeName());
		record.setImageUrl(carModel.getImagePath());
		record.setQuantity(carModel.getQuantity());
		record.setShareRate(carModel.getShareRate());
		record.setForeverRate(carModel.getForeverRate());

		Map<String, Object> priceData = getProductBookPrice(carModel, productBook);
		record.setProductBookId(productBook.getId());
		record.setBookPrice((BigDecimal) priceData.get("bookPrice")); // 定金
		BigDecimal deductibleDisPrice = (BigDecimal) priceData.get("deductibleDisPrice");
		record.setDeductiblePrice(deductibleDisPrice.add(record.getBookPrice())); // 膨胀抵扣金额
		record.setTailPrice((BigDecimal) priceData.get("tailPrice")); // 尾款

		record.setRecordStatus(YgPrepayBookRecord.RecordStatus.WaitingPayDepost);
		record.setCreateTime(new Date());
		record.setStatus(DataStatus.Valid);

		try {
			int row = this.save(record);
			if (row > 0) {
				ygOrderLogService.addOrderLog(record.getRecordCode(), OrderStatus.WaitingPay, "", "定金膨胀记录保存成功 ;record=" + record.toString());
				// 扣减库存
				YgStock reduceStock = new YgStock();
				reduceStock.setSkuCode(carModel.getSkuCode());
				reduceStock.setAmount(carModel.getQuantity());
				ygStockService.reduceStock(Collections.singletonList(reduceStock), "commitProductBookRecord");
				return Message.success(record.getRecordCode()); // 成功提交返回记录编号
			}
		} catch (Exception e) {
			ygOrderLogService.addOrderLog(record.getRecordCode(), OrderStatus.WaitingPay, "", "定金膨胀记录保存失败;record=" + record.toString());
			logger.error("定金膨胀记录保存失败。recordCode=" + record.getRecordCode() + ",e=" + ExceptionUtil.getExceptionMsg(e));
			e.printStackTrace();
		}
		return Message.error("定金膨胀记录保存失败。", null);
	}

	@Override
	public Map<String, Object> getProductBookPrice(YgShoppingCarModel carModel, YgProductBook productBook) {
		// 定金金额
		BigDecimal bookPrice = productBook.getBookMoney();
		// 膨胀抵扣金额
		BigDecimal deductiblePrice = productBook.getDeductibleMoney();
		//商品总额
		BigDecimal productPrice = carModel.getSalesPrice().multiply(BigDecimal.valueOf(carModel.getQuantity()));
		// 尾款总额
		BigDecimal tailPrice = productPrice.subtract(deductiblePrice);
		// 特例品金额
		BigDecimal specialPrice = carModel.getIsSpecial() ? tailPrice : BigDecimal.ZERO;
		Map<String, Object> data = new HashMap<>();
		data.put("productPrice", productPrice);
		data.put("bookPrice", bookPrice);
		data.put("deductibleDisPrice", deductiblePrice.subtract(bookPrice));
		data.put("tailPrice", tailPrice);
		data.put("specialPrice", specialPrice);
		return data;
	}

	private List<ProductBookRecordModel> findList(QueryInfo queryInfo, String q, Long userId, YgPrepayBookRecord.RecordStatus recordStatus, String userName) {
		return ygPrepayBookRecordMapper.selectSuper(queryInfo, q, userId, recordStatus, userName);
	}

	@Override
	public List<ProductBookRecordModel> findList(QueryInfo queryInfo, String q, Long userId, YgPrepayBookRecord.RecordStatus recordStatus) {
		return this.findList(queryInfo, q, userId, recordStatus, null);
	}

	@Override
	public Message validateProductWithProductBook(Long userId, BaseSkuInfo skuInfo) {
		YgProductBook productBook = ygProductBookService.findBySkuId(skuInfo.getSkuId()); // 获取商品参与的活动信息
		if (productBook == null || !productBook.inValidBookTime(DateConvertUtils.getDateStart(new Date()))) {
			return Message.error("该商品没有参与定金膨胀活动，请刷新页面正常下单", null);
		}
		List<YgShoppingCarModel> carModelList = ygShoppingCarService.findItemInfo(Collections.singletonList(skuInfo), userId, PromotionType.Ordinary);
		if (CollectionUtils.isEmpty(carModelList)) {
			return Message.error(documentConstant.getCAR_IS_EMPTY(), null);
		}
		Map<String, Object> extra = new HashMap<>();
		extra.put("productBook", productBook);
		extra.put("carList", carModelList);
		return Message.success(extra);
	}

	@Override
	public Message processItemInfoWithRecordList(List<ProductBookRecordModel> recordList, Long userId, Long giftSkuId) {
		if (CollectionUtils.isEmpty(recordList)) {
			return Message.error("无结算活动订单", null);
		}
		Map<Long, BaseSkuInfo> skuInfoMap = new HashMap<>();
		BigDecimal totalProductPrice = BigDecimal.ZERO;
		BigDecimal totalBookPrice = BigDecimal.ZERO;
		BigDecimal totalDeductiblePrice = BigDecimal.ZERO;
		BigDecimal totalTailPrice = BigDecimal.ZERO;
		for (ProductBookRecordModel record : recordList) {
			if (!skuInfoMap.containsKey(record.getSkuId())) {
				skuInfoMap.put(record.getSkuId(), new BaseSkuInfo(record.getSkuId(), record.getQuantity()));
			} else {
				BaseSkuInfo skuInfo = skuInfoMap.get(record.getSkuId());
				skuInfo.setQuantity(skuInfo.getQuantity() + record.getQuantity());
			}
			// 各项金额合计
			totalProductPrice = totalProductPrice.add(record.getSalePrice().multiply(BigDecimal.valueOf(record.getQuantity())));
			totalBookPrice = totalBookPrice.add(record.getBookPrice());
			totalDeductiblePrice = totalDeductiblePrice.add(record.getDeductiblePrice());
			totalTailPrice = totalTailPrice.add(record.getTailPrice());
		}
		List<BaseSkuInfo> skuInfoList = new ArrayList<>(skuInfoMap.values());
		List<YgShoppingCarModel> carModelList = ygShoppingCarService.findItemInfo(skuInfoList, userId, PromotionType.Ordinary);
		if (giftSkuId != null) {
			BaseSkuInfo skuInfo = new BaseSkuInfo(giftSkuId, 1L);
			List<YgShoppingCarModel> list = ygShoppingCarService.findItemInfo(Collections.singletonList(skuInfo), userId, PromotionType.Ordinary);
			YgShoppingCarModel giftCardModel = list.get(0);
			giftCardModel.setSalesType(PromotionType.ManZeng);
			giftCardModel.setSalesPrice(BigDecimal.ZERO);
			carModelList.add(giftCardModel);
		}
		Map<String, Object> data = new HashMap<>();
		data.put("productPrice", totalProductPrice);
		data.put("bookPrice", totalBookPrice);
		data.put("deductibleDisPrice", totalDeductiblePrice.subtract(totalBookPrice));
		data.put("tailPrice", totalTailPrice);
		data.put("carList", carModelList);
		data.put("expressPrice", ygOrderService.getExpressPrice(totalTailPrice, userId));
		return Message.success(data);
	}

	@SuppressWarnings("unchecked")
	@Override
	public Message commitOrder(Long userId, String userName, List<ProductBookRecordModel> recordList, CommitOrderRequestParam requestParam, SalesPlatform salesPlatform) {
		if (CollectionUtils.isEmpty(recordList)) {
			return Message.error("无结算活动订单", null);
		}
		ygOrderLogService.addOrderLog(userId, OrderStatus.WaitingPay, userName, "活动订单合并提交，提交参数：requestParam=" + requestParam.toString());
		/*
		 * 校验商品信息
		 */
		Message itemInfoMsg = this.processItemInfoWithRecordList(recordList, userId, requestParam.getGiftSkuId());
		if (!Message.isSuccess(itemInfoMsg)) {
			ygOrderLogService.addOrderLog(userId, OrderStatus.WaitingPay, userName, "活动订单合并提交，校验商品信息异常：message=" + itemInfoMsg.getContent());
			return itemInfoMsg;
		}
		Map<String, Object> itemInfoMap = (Map<String, Object>) itemInfoMsg.getExtra();
		List<YgShoppingCarModel> carList = (List<YgShoppingCarModel>) itemInfoMap.get("carList");
		/*
		 * 校验收货地址
		 */
		Message addressMsg = ygUserAddressService.validateUserAddress(userId, requestParam.getUserAddressId(), requestParam.getIdentityNo(), carList, requestParam.getOrderType());
		if (!Message.isSuccess(addressMsg)) {
			ygOrderLogService.addOrderLog(userId, OrderStatus.WaitingPay, userName, "活动订单合并提交，校验收货地址异常：message=" + addressMsg.getContent());
			return addressMsg;
		}
		Map<String, Object> addressExtra = (Map<String, Object>) addressMsg.getExtra();
		YgUserAddress address = (YgUserAddress) addressExtra.get("address");
		Boolean trustoneOrderFlag = (Boolean) addressExtra.get("trustoneOrderFlag"); // 是否为保税仓订单

		BigDecimal productPrice = (BigDecimal) itemInfoMap.get("productPrice"); // 商品总额
		BigDecimal bookPrice = (BigDecimal) itemInfoMap.get("bookPrice"); // 定金金额
		BigDecimal deductibleDisPrice = (BigDecimal) itemInfoMap.get("deductibleDisPrice");    // 抵扣金额
		BigDecimal tailPrice = (BigDecimal) itemInfoMap.get("tailPrice");    // 尾款金额
		BigDecimal totalPrice = tailPrice; // 订单金额
		/*
		 * 验证优惠券
		 */
		YgCouponDetail couponDetail = null;
		BigDecimal couponPrice = BigDecimal.ZERO;
		if (requestParam.getCouponDetailId() != null) {
			couponDetail = ygCouponDetailService.findById(requestParam.getCouponDetailId(), userId);
			Message couponMsg = ygOrderService.validateCoupon(couponDetail, tailPrice, false, carList, salesPlatform);
			if (!Message.isSuccess(couponMsg)) {
				ygOrderLogService.addOrderLog(userId, OrderStatus.WaitingPay, userName, "活动订单合并提交，校验优惠券异常：message=" + couponMsg.getContent());
				return couponMsg;
			}
			couponPrice = (BigDecimal) couponMsg.getExtra();// 优惠卷金额
			totalPrice = totalPrice.compareTo(couponPrice) <= 0 ? BigDecimal.ZERO : totalPrice.subtract(couponPrice);
		}
		/*
		 * 验证满减
		 */
		Map<String, Object> manJian = ygOrderService.getManJianPrice(totalPrice, requestParam.getFormId(), userId);
		Boolean useCoupon = (Boolean) manJian.get("useCoupon"); // 满减活动是否允许使用优惠券
		BigDecimal manJianPrice = (BigDecimal) manJian.get("manjianPrice");// 满减金额
		if (!useCoupon) {
			manJianPrice = BigDecimal.ZERO;
		} else {
			totalPrice = totalPrice.compareTo(manJianPrice) <= 0 ? BigDecimal.ZERO : totalPrice.subtract(manJianPrice);
		}
		/*
		  验证包邮卡券
		 */
		BigDecimal expressPrice = ygOrderService.getExpressPrice(totalPrice, userId); // 运费
		YgCardCouponDetail expressCard = null;
		if (expressPrice.compareTo(BigDecimal.ZERO) > 0 && requestParam.getExpressCardId() != null) {
			expressCard = ygCardCouponDetailService.findById(requestParam.getExpressCardId());
			if (expressCard == null || expressCard.getUseStatus().equals(UseStatus.Used)) {
				ygOrderLogService.addOrderLog(userId, OrderStatus.WaitingPay, userName, "活动订单合并提交，包邮卡券异常, cardId:" + requestParam.getExpressCardId());
				return Message.error("包邮卡券异常，请重试", null);
			}
			if (expressCard.getEndDate().before(DateConvertUtils.getDateStart(new Date()))) {
				ygOrderLogService.addOrderLog(userId, OrderStatus.WaitingPay, userName, "活动订单合并提交，包邮卡券过期, cardId:" + requestParam.getExpressCardId());
				return Message.error("包邮卡券过期，请重试", null);
			}
			expressPrice = BigDecimal.ZERO;
		}
		totalPrice = totalPrice.add(expressPrice);
		/*
		  验证支付的成长基金
		 */
		BigDecimal accountPrice = requestParam.getAccountPrice();
		Message validateAccountPriceMsg = ygOrderService.validateAccountPrice(userId, accountPrice, totalPrice);
		if (!Message.isSuccess(validateAccountPriceMsg)) {
			ygOrderLogService.addOrderLog(userId, OrderStatus.WaitingPay, userName, "活动订单合并提交，校验支付的成长基金异常, message:"
					+ validateAccountPriceMsg.getContent());
			return validateAccountPriceMsg;
		}
		totalPrice = totalPrice.compareTo(accountPrice) <= 0 ? BigDecimal.ZERO : totalPrice.subtract(accountPrice);
		/*
		 * 验证最终的订单支付金额
		 */
		if (totalPrice.compareTo(requestParam.getTotalPrice()) != 0) {
			ygOrderLogService.addOrderLog(userId, OrderStatus.WaitingPay, userName, "活动订单合并提交，订单金额明细：productPrice=" + productPrice
					+ ";bookPrice=" + bookPrice + ";deductibleDisPrice=" + deductibleDisPrice + ";tailPrice" + tailPrice + ";expressPrice=" + expressPrice
					+ ";manJianPrice=" + manJianPrice + ";couponPrice=" + couponPrice + ";accountPrice=" + accountPrice + ";totalPrice=" + totalPrice);
			return Message.error(documentConstant.getORDER_PRICE_YOUWU(), null);
		}
		List<YgShoppingCarModel> packs = getPackModelList(recordList, carList);
		/*
		 * 提交订单
		 */
		Message saveMainOrderMsg = ygOrderService.saveMainOrder(address, couponDetail, couponPrice, userId, userName, totalPrice, accountPrice, productPrice,
				manJianPrice, expressPrice, BigDecimal.ZERO, deductibleDisPrice, BigDecimal.ZERO, BigDecimal.ZERO, requestParam.getAppType(),
				requestParam.getPayType(), requestParam.getSourceCode(), carList, packs, requestParam.getFormId(), requestParam.getGroupBuyId(),
				requestParam.getOrderType(), requestParam.getUserRemark(), expressCard, requestParam.getPlatformNo(), trustoneOrderFlag, Boolean.FALSE,salesPlatform);
		if (Message.isSuccess(saveMainOrderMsg)) {
			Map<String, Long> map = (Map<String, Long>) saveMainOrderMsg.getExtra();
			writeBackBookRecord(recordList, map.get("orderId"));
		}
		return saveMainOrderMsg;
	}

	/**
	 * 定金活动单合并提交成为订单规则:
	 * 	 订单商品总额=所有商品的（实际销售价*数量）之和；
	 * 	 订单金额=实际需要支付金额（包括所有活动单定金金额之和）；
	 * 	 膨胀抵扣优惠以自选包优惠的形式体现；
	 * 	 所有定金活动商品在订单明细中以自选包商品形式体现；
	 * 	 明细商品类型为Ordinary;
	 * @param recordList 活动记录信息
	 * @param carList	购物车信息
	 * @return List
	 */
	private List<YgShoppingCarModel> getPackModelList(List<ProductBookRecordModel> recordList, List<YgShoppingCarModel> carList) {
		List<YgShoppingCarModel> packs = new ArrayList<>();
		Map<Long, List<ProductBookRecordModel>> recordMap = recordList.stream().collect(Collectors.groupingBy(ProductBookRecordModel::getSkuId));
		carList.forEach(car -> {
			if (recordMap.containsKey(car.getSkuId())) {
				List<ProductBookRecordModel> modelList = recordMap.get(car.getSkuId());
				BigDecimal skuBookPrice = BigDecimal.ZERO;
				BigDecimal skuTailPrice = BigDecimal.ZERO;
				for (ProductBookRecordModel model : modelList) {
					skuBookPrice = skuBookPrice.add(model.getBookPrice());
					skuTailPrice = skuTailPrice.add(model.getTailPrice());
				}
				car.setPackId(car.getSkuId());
				car.setPackPrice(skuBookPrice.add(skuTailPrice));
				car.setProductAmount(car.getQuantity());
				car.setSalesType(PromotionType.Ordinary);
				packs.add(car);
			}
		});
		return packs;
	}

	private void writeBackBookRecord(List<ProductBookRecordModel> recordList, Long orderId) {
		for (ProductBookRecordModel recordModel : recordList) {
			YgPrepayBookRecord record = new YgPrepayBookRecord();
			record.setId(recordModel.getId());
			record.setOrderId(orderId);
			update(record);
		}
	}

	@Override
	public Message validateRecordCode(String recordCode) {
		if (StringUtils.isBlank(recordCode)) {
			return Message.error("无结算活动记录", null);
		}
		List<Long> recordCodeList = Arrays.stream(recordCode.split(",")).map(o -> Long.valueOf(o.trim())).collect(Collectors.toList());
		List<ProductBookRecordModel> recordList = this.findByRecordCode(recordCodeList);
		if (CollectionUtils.isEmpty(recordCodeList)) {
			return Message.error("无结算活动记录", null);
		}
		Date now = new Date();
		for (ProductBookRecordModel record : recordList) {
			if (!YgPrepayBookRecord.RecordStatus.WaitingPayFinal.equals(record.getRecordStatus())) {
				return Message.error("活动订单：" + record.getRecordCode() + "状态异常", null);
			}
			if (record.getOrderId() != null) {
				return Message.error("活动记录：" + record.getRecordCode() + "已生成订单", null);
			}
			if (!record.inValidTailMoneyTime(DateConvertUtils.getDateStart(now))) {
				return Message.error("活动订单：" + record.getRecordCode() + "不在支付尾款有效期内", null);
			}
		}
		return Message.success(recordList);
	}

	@Override
	public List<ProductBookRecordModel> findByOrderId(Long orderId, YgPrepayBookRecord.RecordStatus recordStatus) {
		if (orderId == null) {
			return new ArrayList<>();
		}
		return ygPrepayBookRecordMapper.selectByOrderId(orderId, recordStatus);
	}

	@Override
	public Message cancelRecord(ProductBookRecordModel recordModel) {
		ygOrderLogService.addOrderLog(recordModel.getRecordCode(), OrderStatus.TradeClosed, "", "取消活动订单");
		YgPrepayBookRecord record = new YgPrepayBookRecord();
		record.setId(recordModel.getId());
		record.setRecordStatus(YgPrepayBookRecord.RecordStatus.Cancel);
		record.setCancelTime(new Date());
		this.update(record);
		backStock(recordModel);
		return Message.success(null);
	}

	@Override
	public Message cancelRecord(Long recordCode) {
		ProductBookRecordModel recordModel = this.findByRecordCode(recordCode);
		if (recordModel == null) {
			return Message.error("活动订单不存在，活动单号：" + recordCode, null);
		}
		/*if (!YgPrepayBookRecord.RecordStatus.WaitingPayDepost.equals(recordModel.getRecordStatus())) {
			return Message.error("该活动订单不符合退定金条件，活动单号：" + recordCode, null);
		}*/
		return this.cancelRecord(recordModel);
	}

	@Override
	public Message refundRecord(Long recordCode) {
		ProductBookRecordModel recordModel = this.findByRecordCode(recordCode);
		if (recordModel == null) {
			return Message.error("活动订单不存在，活动单号：" + recordCode, null);
		}
		if (!YgPrepayBookRecord.RecordStatus.WaitingPayFinal.equals(recordModel.getRecordStatus())) {
			return Message.error("该活动订单不符合退定金条件，活动单号：" + recordCode, null);
		}
		return refundRecord(recordModel);
	}

	private Message refundRecord(ProductBookRecordModel recordModel) {
		Long recordCode = recordModel.getRecordCode();
		YgOrderPayment payment = ygOrderPaymentService.findByOrderId(recordCode.toString());
		if (payment == null) {
			return Message.error("该活动订单定金支付流水不存在，活动单号：" + recordCode, null);
		}
		try {
			if (!payment.getPayType().equals(PayType.Alipay)) {
				ygReturnOrderService.applyRefundNew(payment.getPlatformNo(), payment.getPayType(), payment.getAppType(), recordCode.toString(), payment.getOrderPayCode(),
						recordModel.getBookPrice(), recordModel.getBookPrice(), "系统自动退定金");
				ygReturnOrderLogService.addReturnOrderLog(recordCode.toString(), "定金已退款成功，感谢您对我们工作的支持（预计银行到账1~5个工作日）", ReturnStatus.Complete,
						"系统自动退定金", "");
			} else {
				ygReturnOrderLogService.addReturnOrderLog(recordCode.toString(), "定金退款失败，不支持支付宝支付自动退款，payCode=" + payment.getOrderPayCode(),
						ReturnStatus.Cancel, "系统自动退定金", "");
				return Message.error("不支持支付宝支付自动退款", null);
			}
			updateRecordByRefund(recordModel);
			backStock(recordModel);
			return Message.success(null);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("定金退款异常,recordCode=" + recordCode + "，message:" + ExceptionUtil.getExceptionMsg(e));
			ygReturnOrderLogService.addReturnOrderLog(recordCode.toString(), "定金退款异常", ReturnStatus.Cancel,
					"系统自动退定金", "");
		}
		return Message.error("定金退款异常", null);
	}

	private void updateRecordByRefund(ProductBookRecordModel recordModel) {
		YgPrepayBookRecord record = new YgPrepayBookRecord();
		record.setId(recordModel.getId());
		record.setRecordStatus(YgPrepayBookRecord.RecordStatus.RefundSuccess);
		record.setRefundTime(new Date());
		this.update(record);
	}

	/**
	 * 未绑定订单的活动记录取消或退款时需要还库存
	 * @param recordModel 活动记录
	 */
	private void backStock(ProductBookRecordModel recordModel) {
		if (recordModel.getOrderId() == null) {
			YgStock stock = new YgStock();
			stock.setSkuCode(recordModel.getSkuCode());
			stock.setAmount(recordModel.getQuantity());
			ygStockService.backStock(Collections.singletonList(stock), "活动订单定金退款");
		}
	}

	@Override
	public List<ProductBookRecordModel> findBetweenDate(Date startDate, Date endDate, YgPrepayBookRecord.RecordStatus recordStatus) {
		return ygPrepayBookRecordMapper.selectBetweenDate(startDate, endDate, recordStatus == null ? null : recordStatus.name());
	}

	@Override
	public List<ProductBookRecordModel> findByBookId(Long bookId, YgPrepayBookRecord.RecordStatus recordStatus) {
		return ygPrepayBookRecordMapper.selectByBookId(bookId, recordStatus);
	}

	@Override
	public Message refundRecordByReturnCode(String returnCode, BigDecimal refundPrice) {
		YgReturnOrder returnOrder = ygReturnOrderService.findDetailByReCode(returnCode);
		List<ProductBookRecordModel> recordList = this.findByOrderId(returnOrder.getOrderId(), YgPrepayBookRecord.RecordStatus.Complete);
		if (CollectionUtils.isEmpty(recordList)) { // 该订单是购物车结算下单
			return Message.success(BigDecimal.ZERO);
		}
		List<Long> skuIdList = returnOrder.getReturnOrderDetails().stream().map(YgReturnOrderDetail::getSkuId).collect(Collectors.toList());
		List<ProductBookRecordModel> refundList = new ArrayList<>();
		BigDecimal bookPrice = BigDecimal.ZERO;
		for (ProductBookRecordModel model : recordList) {
			if (skuIdList.contains(model.getSkuId())) {
				refundList.add(model);
				bookPrice = bookPrice.add(model.getBookPrice());
			}
		}
		/*if (refundPrice.compareTo(bookPrice) < 0) {
			return Message.error("退款金额不得小于定金金额", null);
		}*/
		for (ProductBookRecordModel record : refundList) {
			Message msg = this.refundRecord(record);
			if (!Message.isSuccess(msg)) {
				return msg;
			}
		}
		return Message.success(bookPrice);
	}

	@Override
	public List<ProductBookRecordModel> findForCancel(Date startDate) {
		return ygPrepayBookRecordMapper.selectForCancel(startDate);
	}

	/**
	 * 过滤掉未参与退款的活动单定金
	 * @param order 订单信息
	 * @param returnInfo 退款信息
	 */
	@Override
	public void checkBookOrderForReturn(YgOrder order, YgReturnInfoModel returnInfo) {
		List<ProductBookRecordModel> recordModelList = this.findByOrderId(order.getOrderId(), YgPrepayBookRecord.RecordStatus.Complete);
		BigDecimal bookPrice = BigDecimal.ZERO;
		if (CollectionUtils.isEmpty(recordModelList)) {
			return;
		}
		List<Long> skuIdList = returnInfo.getSkuInfos().stream().map(ReturnSkuInfo::getSkuId).collect(Collectors.toList());
		for (ProductBookRecordModel recordModel : recordModelList) {
			if (!skuIdList.contains(recordModel.getSkuId())) {
				bookPrice = bookPrice.add(recordModel.getBookPrice());
			}
		}
		order.setTotalPrice(order.getTotalPrice().subtract(bookPrice));
	}

	@Override
	public void refundRecord(Long orderId, List<ProductBookRecordModel> modelList) {
		try {
			for (ProductBookRecordModel model :
					modelList) {
				this.refundRecord(model.getRecordCode()); // 退定金
			}
			if (orderId != 0L) { // 取消绑定订单
				ygOrderService.cancelOrder(orderId, modelList.get(0).getUserId(), "", "尾款支付结束，退定金并取消订单");
			}
		} catch (Exception e) {
			List<Long> recordCodeList = modelList.stream().map(ProductBookRecordModel::getRecordCode).collect(Collectors.toList());
			logger.error("orderId:" + orderId + ";recordCodeList=" + recordCodeList.toString() + ";" + e.getMessage(), e);
		}
	}

	@Override
	public void asyncUpdateRecordByCancelOrder(Long orderId) {
		executorService.execute(() -> updateRecordByCancelOrder(orderId));
	}

	@Override
	public int updateRecordByCancelOrder(Long orderId) {
		if (orderId == null) {
			return 0;
		}
		return ygPrepayBookRecordMapper.updateRecordByCancelOrder(orderId);
	}

	@Override
	public void cancelRecord(Long orderId, List<ProductBookRecordModel> modelList) {
		try {
			YgUser user = null;
			for (ProductBookRecordModel model :
					modelList) {
				try {
					if (user == null || !model.getUserId().equals(user.getId())) {
						user = ygUserService.findById(model.getUserId());
					}
					this.cancelRecord(model.getRecordCode());
					ygCouponDetailService.receiveCoupon(CANCELBOOK_COUPON_ID, user);
				} catch (Exception e) {
					logger.error(e.getMessage(), e);
				}
			}
			if (orderId != 0L) { // 取消绑定订单
				ygOrderService.cancelOrder(orderId, user.getId(), user.getUserName(), "尾款支付结束，赠送优惠券并取消订单");
			}
		} catch (Exception e) {
			List<Long> recordCodeList = modelList.stream().map(ProductBookRecordModel::getRecordCode).collect(Collectors.toList());
			logger.error("orderId:" + orderId + ";recordCodeList=" + recordCodeList.toString() + ";" + e.getMessage(), e);
		}
	}
	@Override
	public List<Map<String, Object>> search(Long id) {
		return ygPrepayBookRecordMapper.selectBookTotal(id);
	}

	@Override
	public void asyncUpdateRecordByCancelOrder(List<Long> orderIdList) {
		executorService.execute(() -> {
			orderIdList.forEach(this::updateRecordByCancelOrder);
		});
	}
}

